#include <string.h>
#include <iostream>

using std::cout;
using std::endl;

/* char *pstr = "hello"; */
int arr[10] = {1, 3, 5, 7, 9};
/* arr.operator[](idx) */
/* operator[](size_t idx) */

/* char a = '\0'; */

class CharArray
{
public:
    CharArray(size_t sz = 10)
    : _size(sz)
    , _pdata(new char[_size]())
    {
        cout << "CharArray(size_t = 10)" << endl;
    }

    //下标访问运算符也是以成员函数的形式进行的重载
    //重载下标访问运算符的好处:
    //1、比C数组的下标要安全
    //2、如果需要的话，自定义类型可以重载下标访问运算符
    //3、下标访问运算符的参数可以是任意类型
    //
    //Q:什么时候需要加引用呢?
    //A:1、像流这种拷贝构造函数删除的时候，传参以及函数的
    //返回类型是类类型的时候一定要用引用
    //2、如果实体的生命周期比函数的生命周期要大的话，尽量
    //的将函数的返回类型写成引用
    //3、如果函数的参数是类类型，尽量可以将其设计为引用
    //第二点与第三点，都在考虑的是拷贝构造函数的调用时机
    char &operator[](size_t idx)
    {
        if(idx < size())
        {
            return _pdata[idx];
        }
        else
        {
            static char nullchar = '\0';
            return nullchar;
            /* return a; */
        }
    }

    char &operator[](size_t idx) const
    {
        if(idx < size())
        {
            return _pdata[idx];
        }
        else
        {
            static char nullchar = '\0';
            return nullchar;
        }
    }

    size_t size() const
    {
        return _size;
    }

    ~CharArray()
    {
        cout << "~CharArray()" << endl;
        if(_pdata)
        {
            delete [] _pdata;
            _pdata = nullptr;
        }
    }
private:
    size_t _size;
    char *_pdata;
};

void test()
{
    //将pstr指向的内容拷贝到ca对象中
    const char *pstr = "helloworld";
    CharArray ca(strlen(pstr) + 1);
    for(size_t idx = 0; idx != ca.size(); ++idx)
    {
        /* ca.operator[](idx) = pstr[idx]; */
        //放在赋值符号左边的是左值，但是左值不一定能放在赋值
        //符号的左边
        /* &ca[idx];//ok */
        ca[idx] = pstr[idx];
        
    }

    for(size_t idx = 0; idx != ca.size(); ++idx)
    {
        /* cout << ca[idx] << "  "; */
        cout << ca.operator[](idx) << "  ";
    }
    cout << endl;

    const CharArray ca2(10);
    cout << ca2[0] << endl;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

